﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Minestorm.Retro.GameLogic
{
    public static class CollisionHelper
    {
        static bool pnpoly(int nvert, float[] vertx, float[] verty, float testx, float testy)
        {
            int i, j;
            bool c = false;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                if (((verty[i] > testy) != (verty[j] > testy)) &&
                 (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
                    c = !c;
            }
            return c;
        }

        public static Boolean CheckPointCollision(Vector3[] points, Matrix world, int shellLineCount, VertexPositionColor[] vertices, out int vectorIndex)
        {
            int v = -1;

            foreach (var p in points)
            {
                v++;
                float[] vertx = new float[shellLineCount], verty = new float[shellLineCount];
                Vector3 v1;

                for (var i = 0; i < shellLineCount; i++)
                {
                    v1 = Vector3.Transform(vertices[i].Position, world);

                    vertx[i] = v1.X;
                    verty[i] = v1.Y;
                }
                if (pnpoly(shellLineCount, vertx, verty, p.X, p.Y))
                {
                    vectorIndex = v;
                    return true;
                }
            }

            vectorIndex = -1;
            return false;
        }

        public static Boolean CheckLineCollision(Vector2 ls, Vector2 le, Matrix world, int shellLineCount, VertexPositionColor[] vertices)
        {
            Vector3 v1, v2;

            for (var i = 0; i < shellLineCount; i++)
            {
                v1 = Vector3.Transform(vertices[i].Position, world);
                v2 = Vector3.Transform(vertices[(i + 1) % shellLineCount].Position, world);

                if (CheckLineIntersection(ls, le, new Vector2(v1.X, v1.Y), new Vector2(v2.X, v2.Y)))
                    return true;
            }

            return false;
        }

        static bool CheckLineIntersection(Vector2 a, Vector2 b, Vector2 c, Vector2 d)
        {
            float denominator = ((b.X - a.X) * (d.Y - c.Y)) - ((b.Y - a.Y) * (d.X - c.X));
            float numerator1 = ((a.Y - c.Y) * (d.X - c.X)) - ((a.X - c.X) * (d.Y - c.Y));
            float numerator2 = ((a.Y - c.Y) * (b.X - a.X)) - ((a.X - c.X) * (b.Y - a.Y));

            if (denominator == 0) return numerator1 == 0 && numerator2 == 0;

            float r = numerator1 / denominator;
            float s = numerator2 / denominator;

            return (r >= 0 && r <= 1) && (s >= 0 && s <= 1);
        }
    }
}
